﻿using Configs;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


namespace Configs
{
	public class InputReaderMan
	{
		public bool UseJoy { get; } = false;
		private Transform transform;
		private readonly float aimDistance = 500f;
		private Vector3 aimV3;
		private Vector3 srceenCenten;
		private int frame = -1;
		/// <summary>
		/// 使用键鼠控制
		/// </summary>
		public InputReaderMan()
		{
			InputConfigDic.Add(0, new InputReaderConfig());
		}
		/// <summary>
		/// 使用手柄控制
		/// </summary>
		/// <param name="transform">受控角色的Transform</param>
		public InputReaderMan(Transform transform)
		{
			this.transform = transform;
			UseJoy = true;
			srceenCenten = new Vector3(Screen.width / 2F, Screen.height / 2f, 0);
			InputConfigDic.Add(0, new InputReaderConfig());
		}
		public Dictionary<int, InputReaderConfig> InputConfigDic = new Dictionary<int, InputReaderConfig>();

		public bool Run { get { return CheckInput(Action.Run); } }
		/// <summary>
		/// 普通攻击开始
		/// </summary>
		public bool AttackNormalStart { get { return CheckInputDown(Action.AttackNormalStart); } }
		/// <summary>
		/// 普通攻击结束
		/// </summary>
		public bool AttackNormalEnd { get { return CheckInputUp(Action.AttackNormalEnd); } }
		/// <summary>
		/// 近战攻击
		/// </summary>
		public bool AttackNear { get { return CheckInput(Action.AttackNear); } }
		public bool InterActive { get { return CheckInputDown(Action.InterActive); } }

		/// <summary>
		/// 滚
		/// </summary>
		public bool Roll { get { return CheckInput(Action.Roll); } }

		public float HorizontalRaw
		{
			get
			{
				float h = Input.GetAxisRaw(InputConfigDic[0].Raws_MoveH);
				return h;
			}
		}
		public float VerticalRaw
		{
			get
			{
				float v = Input.GetAxisRaw(InputConfigDic[0].Raws_MoveV);
				return v;
			}
		}

		Vector3 last=Vector3.one;
		/// <summary>
		/// 获取准心世界坐标
		/// </summary>
		/// <returns></returns>
		public Vector3 AimPosition
		{
			get
			{
				if (Time.frameCount == frame)
				{
					return aimV3;
				}

				frame = Time.frameCount;
				if (UseJoy)
				{
					var x = Input.GetAxisRaw(InputConfigDic[0].Raws_AimH);
					var y = Input.GetAxisRaw(InputConfigDic[0].Raws_AimV);
					Vector3 v3 = new Vector2(x, y).normalized;;
                    //               if (x!=0)
                    //               {
                    //	v3.x *= x/Mathf.Sign(x);
                    //}
                    //               else if(y!=0)
                    //               {
                    //	v3.y *= y / Mathf.Sign(y);
                    //}
                    if (v3==Vector3.zero)
                    {
						return aimV3 = Camera.main.ScreenToWorldPoint(srceenCenten + last * aimDistance);
                    }
                    else
                    {
						last = v3;
					}
					aimV3 = Camera.main.ScreenToWorldPoint(srceenCenten + v3 * aimDistance);
					return aimV3;
				}
				return aimV3 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
			}
		}

		private bool CheckInput(Action index)
		{
			foreach (var item in InputConfigDic.Values)
			{
				if (Input.GetKey(item.keyCodes[(int)index]))
				{
					return true;
				}
			}
			return false;
		}
		private bool CheckInputDown(Action index)
		{
			foreach (var item in InputConfigDic.Values)
			{
				if (Input.GetKeyDown(item.keyCodes[(int)index]))
				{
					return true;
				}
			}
			return false;
		}

		private bool CheckInputUp(Action index)
		{
			foreach (var item in InputConfigDic.Values)
			{
				if (Input.GetKeyUp(item.keyCodes[(int)index]))
				{
					return true;
				}
			}
			return false;
		}


	}

	public class InputReaderConfig
	{
		public KeyCode[] keyCodes { get; private set; } = new KeyCode[] {
			KeyCode.W,
			KeyCode.S,
			KeyCode.A,
			KeyCode.D,
			KeyCode.LeftShift,
			KeyCode.E,
			KeyCode.Mouse0,
			KeyCode.Mouse0,
			KeyCode.Mouse1,
			KeyCode.Space
		};
		public string Raws_MoveH = "Horizontal", Raws_MoveV = "Vertical";
		public string Raws_AimH = "J1_RH", Raws_AimV = "J1_RV";
	}

	enum Action
	{
		Up,
		Down,
		Left,
		Right,
		Run,
		InterActive,
		AttackNormalStart,
		AttackNormalEnd,
		AttackNear,
		Roll
	}

}
